package kltn.business;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import kltn.data.Direction;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.google.android.gms.maps.model.LatLng;

public class DirectionJSON {
	public final static String MODE_DRIVING = "driving";
	public DirectionJSON(){};
	
	public ArrayList<Direction> getWay(LatLng start, LatLng end){
		JSONObject obj=getJsonFromUrl(start, end);
		return getAllDirections(obj);
	}
	
	public JSONObject getJsonFromUrl(LatLng start, LatLng end) {
		String url = "http://maps.googleapis.com/maps/api/directions/json?"
                + "origin=" + start.latitude + "," + start.longitude
                + "&destination=" + end.latitude + "," + end.longitude
                + "&sensor=true&units=metric&mode=driving&alternatives=true";
		JSONObject jObj = null;
		try {
			InputStream is;
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(url);
			HttpResponse httpResponse = httpClient.execute(httpPost);
			is = httpResponse.getEntity().getContent(); 
			BufferedReader br = null;
			StringBuilder sb = new StringBuilder(); 
			String line;
			try {
				br = new BufferedReader(new InputStreamReader(is));
				while ((line = br.readLine()) != null) {
					sb.append(line);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (br != null) {
					try {
						br.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			jObj = new JSONObject(sb.toString());
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return jObj;
	}
	public ArrayList<Direction> getAllDirections(JSONObject obj){
		ArrayList<Direction> list= new ArrayList<Direction>();
		try {
			if(obj.getString("status").equals("OK"))
			{
				JSONArray jroutes=obj.getJSONArray("routes");
				Log.d("test","so duong "+jroutes.length());
				for (int i=0;i<jroutes.length();i++){
					list.add(getDirections(jroutes.getJSONObject(i)));
				}
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
	public Direction getDirections(JSONObject obj)
	{
		Direction dire= new Direction();
		try {
			dire.setSummary(obj.getString("summary"));
			JSONObject jlegs=obj.getJSONArray("legs").getJSONObject(0);
			dire.setDistance(jlegs.getJSONObject("distance").getString("value"));
			dire.setDuration(jlegs.getJSONObject("duration").getString("value"));
			JSONArray jsteps=jlegs.getJSONArray("steps");
			ArrayList<LatLng> points= new ArrayList<LatLng>();
			JSONObject jstart= jlegs.getJSONObject("start_location");
//			Log.d("test","Start: "+jstart.getString("lat")+";"+jstart.getString("lng"));
			points.add(new LatLng(Double.parseDouble(jstart.getString("lat")),Double.parseDouble(jstart.getString("lng"))));
			for (int i=0;i<jsteps.length();i++) {
				JSONObject jstep=jsteps.getJSONObject(i);
				JSONObject jpolyline=jstep.getJSONObject("polyline");
				points.addAll(decodePoly(jpolyline.getString("points")));
				JSONObject jend= jstep.getJSONObject("end_location");
				points.add(new LatLng(Double.parseDouble(jend.getString("lat")),Double.parseDouble(jend.getString("lng"))));
			}
			dire.setPoints(points);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return dire;
	}
	private ArrayList<LatLng> decodePoly(String encoded) {
        ArrayList<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;
        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;
 
            LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
            poly.add(position);
        }
        return poly;
    }
}
